package com.vip8.recorder.service.utils;

import cn.hutool.core.date.StopWatch;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.vip8.recorder.service.utils.yonghui.*;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

@Slf4j
public class YonghuiApiUtil {

    private static final String APIHOST = "https://api.yonghui.com";

    /**
     * 获取TGT票据
     */
    private static final String AUTH_CODE_URL = "/v1/upm/up/auth/code";
    /**
     * 通过TGT票据获取access_token
     */
    private static final String GET_ACCESS_TOKEN_URL = "/v1/upm/up/auth/accessToken";
    /**
     * 获取TGT票据
     */
    private static final String GET_USER_INFO_URL = "/v1/upm/up/userInfo";
    /**
     * 获取TGT票据
     * @param fetchAuthCode
     * @return
     */
    public static YonghuiRespResult authCode(FetchAuthCode fetchAuthCode, String apiHost){
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("获取TGT票据");
        String url =  StrUtil.blankToDefault(apiHost, APIHOST) + AUTH_CODE_URL;
        String body = JSONUtil.toJsonStr(fetchAuthCode);
        String result = StrUtil.EMPTY;
        try {
            result = HttpRequest.post(url)
                    .header(Header.USER_AGENT, "Hutool http")//头信息，多个头信息多次调用此方法即可
                    .header("Content-Type", "application/json; charset=utf-8")
                    .body(body)
                    .timeout(20000)//超时，毫秒
                    .execute()
                    .body();
        } catch (Exception e) {
            log.error("获取TGT票据异常", e);
            e.printStackTrace();
        } finally {
            if(stopWatch.isRunning()){
                stopWatch.stop();
            }
            log.info("获取TGT票据地址:{}", url);
            log.info("获取TGT票据参数:{}", body);
            log.info("获取TGT票据结果:{}", result);
            log.info("获取TGT票据日志:{}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
        }
        return JSON.parseObject(result, YonghuiRespResult.class);
    }
    /**
     * 获取access_token
     * @param fetchTokenVo
     * @return result里的accessToken=通过TGT换取ST票据
     */
    public static YonghuiRespResult getAcessToken(FetchTokenVo fetchTokenVo, String apiHost){
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("获取access_token");
        String url =  StrUtil.blankToDefault(apiHost, APIHOST) + GET_ACCESS_TOKEN_URL;
        String body = JSONUtil.toJsonStr(fetchTokenVo);
        String result = StrUtil.EMPTY;
        try {
            result = HttpRequest.post(url)
                    .header(Header.USER_AGENT, "Hutool http")//头信息，多个头信息多次调用此方法即可
                    .header("Content-Type", "application/json; charset=utf-8")
                    .body(body)
                    .timeout(20000)//超时，毫秒
                    .execute()
                    .body();
        } catch (Exception e) {
            log.error("获取access_token异常", e);
            e.printStackTrace();
        } finally {
            if(stopWatch.isRunning()){
                stopWatch.stop();
            }
            log.info("获取access_token地址:{}", url);
            log.info("获取access_token参数:{}", body);
            log.info("获取access_token结果:{}", result);
            log.info("获取access_token日志:{}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
        }
        return JSON.parseObject(result, YonghuiRespResult.class);
    }
    /**
     * 获取⽤户信息
     * @param fetchUserVo
     * @return 用户信息
     */
    public static YonghuiRespResult getUserInfo(FetchUserVo fetchUserVo, String apiHost){
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("获取⽤户信息");
        String url =  StrUtil.blankToDefault(apiHost, APIHOST) + GET_USER_INFO_URL;
        String body = JSONUtil.toJsonStr(fetchUserVo);
        String result = StrUtil.EMPTY;
        try {
            result = HttpRequest.post(url)
                    .header(Header.USER_AGENT, "Hutool http")//头信息，多个头信息多次调用此方法即可
                    .header("Content-Type", "application/json; charset=utf-8")
                    .body(body)
                    .timeout(20000)//超时，毫秒
                    .execute()
                    .body();
        } catch (Exception e) {
            log.error("获取⽤户信息异常", e);
            e.printStackTrace();
        } finally {
            if(stopWatch.isRunning()){
                stopWatch.stop();
            }
            log.info("获取⽤户信息地址:{}", url);
            log.info("获取⽤户信息参数:{}", body);
            log.info("获取⽤户信息结果:{}", result);
            log.info("获取⽤户信息日志:{}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
        }
        return JSON.parseObject(result, YonghuiRespResult.class);
    }

    public static void main(String[] args) {
        FetchAuthCode fetchAuthCode = FetchAuthCode.builder().build();
        String serviceUrl = "";
        fetchAuthCode.setUsername("");
        fetchAuthCode.setPassword("");
        fetchAuthCode.setService(serviceUrl);
        try {
            YhUserInfo yhUserInfo = YonghuiApiUtil.getUserInfo(fetchAuthCode, "");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 登陆获取用户信息
     * @param fetchAuthCode
     * @param apiHost
     * @return
     */
    public static YhUserInfo getUserInfo(FetchAuthCode fetchAuthCode, String apiHost){
        YhUserInfo yhUserInfo = null;
        String serviceUrl = fetchAuthCode.getService();
        YonghuiRespResult authCodeResult = YonghuiApiUtil.authCode(fetchAuthCode, apiHost);
        if(authCodeResult.isSuccess()){
            JSONObject authCodeJson = JSON.parseObject(authCodeResult.getResult(), JSONObject.class);
            String authCode = authCodeJson.getString("code");
            if(StrUtil.isNotBlank(authCode)){
                FetchTokenVo fetchTokenVo = FetchTokenVo.builder()
                        .code(authCode).service(serviceUrl)
                        .build();
                YonghuiRespResult accessTokenResult = YonghuiApiUtil.getAcessToken(fetchTokenVo, apiHost);
                if(accessTokenResult.isSuccess()){
                    JSONObject accessTokenJson = JSON.parseObject(accessTokenResult.getResult(), JSONObject.class);
                    String accessToken = accessTokenJson.getString("accessToken");
                    if(StrUtil.isNotBlank(accessToken)){
                        FetchUserVo fetchUserVo = FetchUserVo.builder()
                                .accessToken(accessToken)
                                .service(serviceUrl)
                                .build();
                        YonghuiRespResult userInfoResult = YonghuiApiUtil.getUserInfo(fetchUserVo, apiHost);
                        if(userInfoResult.isSuccess()){
                            yhUserInfo = JSON.parseObject(userInfoResult.getResult(), YhUserInfo.class);
                            log.info("用户信息:{}", JSONUtil.toJsonPrettyStr(yhUserInfo));
                            if(ObjectUtil.isEmpty(yhUserInfo)){
                                log.error("获取⽤户信息失败:用户信息为空");
                                throw new RuntimeException("获取⽤户信息失败:用户信息为空");
                            }
                        }else{
                            log.error("获取⽤户信息失败:{}", userInfoResult.getMessage());
                            throw new RuntimeException("获取⽤户信息失败:" + userInfoResult.getMessage());
                        }
                    }else{
                        log.error("获取access_token失败:accessToken为空");
                        throw new RuntimeException("获取access_token失败:accessToken为空");
                    }
                }else{
                    log.error("获取access_token失败:{}", accessTokenResult.getMessage());
                    throw new RuntimeException("获取access_token失败:" + accessTokenResult.getMessage());
                }
            } else {
                log.error("获取auth_code失败:auth_code为空");
                throw new RuntimeException("获取auth_code失败:auth_code为空");
            }
        } else {
            log.error("获取auth_code失败:{}", authCodeResult.getMessage());
            throw new RuntimeException("获取auth_code失败:" + authCodeResult.getMessage());
        }
        return yhUserInfo;
    }

    /**
     * 登陆获取用户信息
     * @param fetchAuthCode
     * @param apiHost
     * @return
     */
    public static YhUserInfo getUserInfoMock(FetchAuthCode fetchAuthCode, String apiHost){
        YhUserInfo yhUserInfo = YhUserInfo.builder()
                .telephoneNumber("18812345678")
                .employeeNumber(fetchAuthCode.getUsername())
                .displayName("测试".concat(RandomUtil.randomString(5)))
                .hcUserId(RandomUtil.randomString(10)).build();
        return yhUserInfo;
    }
}
